package lockDemo;

import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author Ajie
 * @date 2023/8/12
 * @function
 * 结论：乐观锁(AtomicInteger)CAS < 悲观锁(ReentrantLock/Sync) 用时。69ms<159ms
 * demo 对比 1000 thread * 1000次更新。 乐观锁CAS < 悲观锁(ReentrantLock/Sync) 用时。69ms<159ms
 */
public class Lock_Optimistic_Pessimistic_乐观锁_悲观锁_对比 {

    private static final int THREADS = 1000; // 测试的线程数量
    private static final int ITERATIONS = 1000; // 每个线程的迭代次数

    public static void main(String[] args) throws InterruptedException {
        // 悲观锁测试
        PessimisticLockingDemo pessimisticLockingDemo = new PessimisticLockingDemo();
        long startTimePessimistic = System.currentTimeMillis(); // 悲观锁开始时间
        Thread[] pessimisticThreads = new Thread[THREADS];
        for (int i = 0; i < THREADS; i++) {
            pessimisticThreads[i] = new Thread(() -> {
                for (int j = 0; j < ITERATIONS; j++) {
                    pessimisticLockingDemo.updateResource(); // 使用悲观锁更新资源
                }
            });
            pessimisticThreads[i].start();
        }
        for (Thread thread : pessimisticThreads) {
            thread.join(); // 等待所有线程完成
        }
        long endTimePessimistic = System.currentTimeMillis(); // 悲观锁结束时间
        System.out.println("悲观锁执行时间: " + (endTimePessimistic - startTimePessimistic) + " ms");
        System.out.println("悲观锁最终结果是否正确: " + (pessimisticLockingDemo.getResource() == THREADS * ITERATIONS));

        // 乐观锁测试
        OptimisticLockingDemo optimisticLockingDemo = new OptimisticLockingDemo();
        long startTimeOptimistic = System.currentTimeMillis(); // 乐观锁开始时间
        Thread[] optimisticThreads = new Thread[THREADS];
        for (int i = 0; i < THREADS; i++) {
            optimisticThreads[i] = new Thread(() -> {
                for (int j = 0; j < ITERATIONS; j++) {
                    optimisticLockingDemo.updateResource(); // 使用乐观锁更新资源
                }
            });
            optimisticThreads[i].start();
        }
        for (Thread thread : optimisticThreads) {
            thread.join(); // 等待所有线程完成
        }
        long endTimeOptimistic = System.currentTimeMillis(); // 乐观锁结束时间
        System.out.println("乐观锁执行时间: " + (endTimeOptimistic - startTimeOptimistic) + " ms");
        System.out.println("乐观锁最终结果是否正确: " + (optimisticLockingDemo.getResource() == THREADS * ITERATIONS));
    }

    // 悲观锁实现
    static class PessimisticLockingDemo {
        private int resource = 0;
        private final Lock lock = new ReentrantLock();

        //136ms 134ms 149 ms
        public void updateResource() {
            lock.lock(); // 获取锁
            try {
                resource++;
            } finally {
                lock.unlock(); // 释放锁
            }
        }

        //171 ms 156ms 140ms
//       public synchronized void updateResource() {
//                resource++;
//        }

        public int getResource() {
            return resource;
        }
    }

    // 乐观锁实现
    static class OptimisticLockingDemo {
        private final AtomicInteger resource = new AtomicInteger(0);

        public void updateResource() {
            int oldValue;
            do {
                oldValue = resource.get(); // 获取当前值
            } while (!resource.compareAndSet(oldValue, oldValue + 1)); // 尝试使用CAS更新
        }

        public int getResource() {
            return resource.get();
        }
    }
}

